import { ObjHandle } from "../Framework/ObjHandle";
import { VisualEntity } from "./VisualEntity";
import { L2VMessageEnum } from "../Framework/Network/L2VMessageEnum";
import { MsgDispatcher } from "../Framework/Network/MsgDispatcher";

export class VisualEntityManager
{
    allEntities:{[key:number]: ObjHandle<VisualEntity>} = {};
    tiles: any[] = [];

    constructor()
    {
        MsgDispatcher.getInstance().registerMsg(L2VMessageEnum.CreateEntity, this.onCreateEntity);
        MsgDispatcher.getInstance().registerMsg(L2VMessageEnum.DelEntity, this.onDelEntity);
        MsgDispatcher.getInstance().registerMsg(L2VMessageEnum.EntityMessage, this.onEntityMessage);
    }

    tick(dt): void
    {
        for(let entityID in this.allEntities)
        {
            let entity = this.allEntities[entityID];
            if(entity != undefined && entity.isValid())
            {
                entity.instance.tick(dt);
            }
        }
    }
    
    getEntity(entityID: number): ObjHandle<VisualEntity>
    {
        let vEntity = this.allEntities[entityID];
        if(vEntity == undefined)
        {
            return ObjHandle.NULL;
        }
        else
        {
            return vEntity;
        }
    }

    onCreateEntity = (params: any[]) =>
    {
        let entityID: number = params[0];
        let characterID: number = params[1];

        let tileObj:cc.Node = cc.instantiate(this.tiles[characterID]);
        let vEntity:VisualEntity = tileObj.getComponent("VisualEntity");
        cc.find("Canvas/tiles").addChild(tileObj);
        let handle: ObjHandle<VisualEntity> = new ObjHandle<VisualEntity>(vEntity);

        vEntity.entityID = entityID;
        vEntity.characterID = characterID;
        vEntity.self = handle;
        this.allEntities[entityID] = handle;
        vEntity.init();
    }

    onDelEntity = (params: any[]) =>
    {
        let entityID: number = params[0];
        let visualEntity = this.allEntities[entityID];
        if(visualEntity == undefined || visualEntity == null)
        {
            return;
        }

        if(visualEntity.isValid())
        {
            visualEntity.instance.onDestroy();
            visualEntity.instance.node.destroy();
            visualEntity.release();
        }

        this.allEntities[entityID] = null;
    }

    onEntityMessage = (params: any[]) =>
    {
        let msgID: number = params[0];
        let entityID: number = params[1];
        let visualEntity = this.getEntity(entityID);

        if(visualEntity.isValid())
        {
            visualEntity.instance.dispatchMsg(msgID, params);
        }
    }

    destroy(): void
    {
        for(let entityID in this.allEntities)
        {
            let visualEntity = this.allEntities[entityID];
            if(visualEntity == undefined || visualEntity == null)
            {
                continue;
            }

            if(visualEntity.isValid())
            {
                visualEntity.instance.onDestroy();
                visualEntity.release();
            }
        }
        this.allEntities = {};

        MsgDispatcher.getInstance().unregisterMsg(L2VMessageEnum.CreateEntity, this.onCreateEntity);
        MsgDispatcher.getInstance().unregisterMsg(L2VMessageEnum.DelEntity, this.onDelEntity);
        MsgDispatcher.getInstance().unregisterMsg(L2VMessageEnum.EntityMessage, this.onEntityMessage);
    }
}
